import datetime
import time

import requests
import uiautomator2 as u2
import adbutils
import yaml

lark_package_name = 'com.ss.android.lark'
timeout_second = 60


class AndroidDevices:
    def __init__(self, sn: str):
        self.sn = sn
        self.device: u2.Device = u2.connect(self.sn)
    
    def unlock_devices(self, password: str):
        password = str(password)
        self.device.screen_off()
        time.sleep(2)
        screen = self.device.info
        if not screen["screenOn"]:  # 屏幕状态
            self.device.screen_on()
            self.device.swipe(0.5, 0.8, 0.5, 0.3, steps=1)  # 从屏幕下方向上滑动
            if len(password) > 0:
                for num in password:
                    self.device(text=num).click()


def read_target_devices(file_path: str = r'target_devices.yml') -> dict:
    with open(file_path, "r") as file:
        data = yaml.safe_load(file)
    print('yaml:', data)
    return data


def get_connected_devices() -> list:
    devices = adbutils.adb.device_list()
    connected_sn_list = [device.serial for device in devices]
    return connected_sn_list


def call_webhook(status: bool = False, detail: str = ''):
    my_dict2 = {
        "success": status,
        "message": "成功" if status else "失败",
        "detail": detail,
    }
    response = requests.post(
        url='https://www.feishu.cn/flow/api/trigger-webhook/417bd5f69cf2ce17238b9a0648f042fe',
        json=my_dict2
    )
    print(response.request.body.decode("utf-8"))
    print(response.status_code)
    print(response.text)


def select_target_device(target_devices: dict, connected_devices: list, connection_type: str) -> dict:
    device_info = {}
    for target_device in target_devices[connection_type]:
        if target_device["sn"] in connected_devices:
            device_info = target_device
            break
    return device_info


if __name__ == '__main__':
    print('开始')
    
    # 获取当前时间
    now = datetime.datetime.now()
    check_in_time = datetime.time(9, 40)
    check_out_time = datetime.time(6 + 12, 30)
    
    print(now.time(), check_in_time, check_out_time)
    if check_in_time <= now.time() <= check_out_time:
        print('not in target time')
        exit(1)
    
    target_devices: dict = read_target_devices()
    connected_devices: list = get_connected_devices()
    device_info: dict = select_target_device(target_devices, connected_devices, 'wired')
    
    if len(device_info) == 0:
        for target_device in target_devices['remote']:
            if target_device["sn"] not in connected_devices:
                res = adbutils.adb.connect(target_device["sn"])
                print(res, 'res')
    
        connected_devices: list = get_connected_devices()
        device_info: dict = select_target_device(target_devices, connected_devices, 'remote')
    
    print('device_info', device_info)
    android_devices = AndroidDevices(device_info["sn"])
    android_devices.unlock_devices(device_info["passwd"])
    device = android_devices.device
    
    device.app_stop(lark_package_name)
    device.app_start(lark_package_name)
    print(device.app_current())
    
    try:
        device(text="工作台").click(timeout=timeout_second)
        device(text="假勤").click(timeout=timeout_second)
        
        # 如果 for 循环中有 break 字段等导致 for 循环没有正常执行完毕，那么 else 中的内容就不会执行。
        for i in range(300):
            if device(text='已进入打卡范围').exists:
                break
            time.sleep(1)
        else:
            call_webhook(status=False, detail='不在打卡范围')
            exit(1)
        
        if now.time() <= check_in_time:
            device(text="上班打卡").click(timeout=timeout_second)
        elif now.time() >= check_out_time:
            device(text="下班打卡").click(timeout=timeout_second)
        else:
            print('not in target time 2')
            call_webhook(status=False, detail='Not in time range')
        # device(text="更新打卡").click()
    except u2.exceptions.UiObjectNotFoundError as e:
        call_webhook(status=False, detail=str(e))
    else:
        call_webhook(status=True, detail='')
    
    time.sleep(5)
    device.screen_off()
